using System.Data;
using System.Data.SqlClient;
using System.Web.Services;
using System.Web;
using System.Xml;
using System;

/*	-----------------------------------------------------------------------	
	Copyright:	umlungu consulting (pty) ltd
	Author:		Alan Benington
	Started:	2004-08-10
	Status:		live
	Version:	1.0.4
	License:	GNU General Public License
	-----------------------------------------------------------------------	*/
	
namespace umlungu.engineX.workflowX {
	/// <summary>
	/// The x_workitems class. 
	/// </summary>
	public class x_workitems : x_DbData {
		#region Constants
		/// <summary>workitemsxml constant</summary>
		protected const string workitemsxml = "<workflowX><workitems/></workflowX>";
		/// <summary>error_agent constant</summary>
		protected const string error_agent 	= "The agent identifier is null.";
		/// <summary>error_nullid constant</summary>
		protected const string error_nullid	= "The workitems identifier is null.";
		#endregion

		#region Invisible properties
		/// <summary>workitems property</summary>
		protected XmlDocument workitems;
		/// <summary>id property</summary>
		protected int id;
		#endregion

		#region Visible properties
		/// <summary>WorkFlow property</summary>
		public XmlElement WorkFlow {
			get { return workitems.DocumentElement; }
		}
		/// <summary>WorkItems property</summary>
		public XmlElement WorkItems {
			get { return (XmlElement) workitems.SelectSingleNode("/workflowX/workitems"); }
		}
		/// <summary>The identifier of the list. Typically the user, agent or owner identifier</summary>
		public int ID {
			get { return id; }
			set { id = value; 
				WorkItems.SetAttribute("id", id.ToString());
			}
		}
		#endregion

		#region Constructors/Destructors
		/// <summary>Constructor</summary>
		/// <param name="DSN">the dsn (from web.config)</param>
		public x_workitems(string DSN) : base(DSN) {
			initialise();
		}
		#endregion

		#region Public methods
		///	<summary>
		///	Retreives a work item from the database
		///	</summary>
		public void Get(int thisid) {
			ID = thisid;
			Get();
		}
		///	<summary>
		///	Retreives a list of work-items, filtered by the current user
		///	</summary>
		public void Get() {
			getWorkItems((int) SelectionIdentifier.byUser);
		}
		/// <overloads>Retrieves a list of work-items</overloads>
		///	<summary>
		///	All work-items in the system
		///	</summary>
		public void GetWorkItems() {
			ID = 0;
			getWorkItems(0);
		}
		///	<summary>
		///	Find any work-item by task or user contact
		///	</summary>
		public void GetWorkItems(int taskid, string contactno) {
			getWorkItems(taskid, contactno);
		}
		///	<summary>
		///	Filtered by the specified agent
		///	</summary>
		/// <param name="agentid">The identifier of the 'Agent'</param>
		public void GetWorkItems(string agentid) {
			if (agentid == null || agentid == "")
				throw(new x_exception("error_agent", error_agent));
			GetWorkItems(Convert.ToInt32(agentid));
		}
		///	<summary>
		///	Filtered by the specified agent
		///	</summary>
		/// <param name="agentid">The identifier of the 'Agent'</param>
		public void GetWorkItems(int agentid) {
			ID = agentid;
			getWorkItems((int) SelectionIdentifier.byAgent);
		}
		///	<summary>
		///	Filtered by the specified agent
		///	</summary>
		/// <param name="agentid">The identifier of the 'Agent'</param>
		/// <param name="stateid">The identifier of the 'State'</param>
		/// <param name="statusid">The identifier of the 'Status'</param>
		public void GetWorkItems(int agentid, int stateid, int statusid) {
			ID = agentid;
			getWorkItems((int) SelectionIdentifier.byAgent, stateid, statusid, 0);
		}
		///	<summary>
		///	Filtered by the owner, process, state, status and agent
		///	</summary>
		/// <param name="ownerid">The identifier of the 'Owner'</param>
		/// <param name="processid">The identifier of the 'Process'</param>
		/// <param name="agentid">The identifier of the 'Agent'</param>
		/// <param name="stateid">The identifier of the 'State'</param>
		/// <param name="statusid">The identifier of the 'Status'</param>
		public void GetWorkItems(int ownerid, int processid, int agentid, int stateid, int statusid) {
			ID = agentid;
			getWorkItems(ownerid, processid, stateid, statusid, agentid);
		}
		///	<summary>
		///	Filtered by the owner, process, state, status and agent
		///	</summary>
		/// <param name="ownerid">The identifier of the 'Owner'</param>
		/// <param name="processid">The identifier of the 'Process'</param>
		/// <param name="agentid">The identifier of the 'Agent'</param>
		/// <param name="stateid">The identifier of the 'State'</param>
		/// <param name="statusid">The identifier of the 'Status'</param>
		/// <param name="datefrom">The 'From' date</param>
		/// <param name="dateto">The 'To' date</param>
		public void GetWorkItems(int ownerid, int processid, int agentid, int stateid, int statusid, string datefrom, string dateto) {
			ID = agentid;
			getWorkItems(ownerid, processid, stateid, statusid, agentid, datefrom, dateto);
		}
		/// <overloads>Retreives a list of work-items, filtered by the specified owner, state, status and/or agent</overloads>
		///	<summary>
		///	All work-items for an owner, Owner identifier is numeric
		///	</summary>
		/// <param name="ownerid">The identifier of the 'Owner'</param>
		public void GetWorkItemsByOwner(int ownerid) {
			ID = ownerid;
			getWorkItems((int) SelectionIdentifier.byOwner);
		}
		///	<summary>
		///	All work-items for an owner, Owner identifier is numeric represented as string
		///	</summary>
		/// <param name="ownerid">The identifier of the 'Owner'</param>
		public void GetWorkItemsByOwner(string ownerid) {
			GetWorkItemsByOwner(Convert.ToInt32(ownerid));
		}
		///	<summary>
		///	All work-items for an owner, Owner identifier is numeric represented as string
		///	</summary>
		/// <param name="ownerid">The identifier of the 'Owner'</param>
		/// <param name="stateid">The identifier of the 'State'</param>
		/// <param name="statusid">The identifier of the 'Status'</param>
		/// <param name="agentid">The identifier of the 'Agent'</param>
		public void GetWorkItemsByOwner(string ownerid, int stateid, int statusid, int agentid) {
			GetWorkItemsByOwner(Convert.ToInt32(ownerid), stateid, statusid, agentid);
		}
		///	<summary>
		///	All work-items for an owner, Owner identifier is numeric represented as string
		///	</summary>
		/// <param name="ownerid">The identifier of the 'Owner'</param>
		/// <param name="stateid">The identifier of the 'State'</param>
		/// <param name="statusid">The identifier of the 'Status'</param>
		/// <param name="agentid">The identifier of the 'Agent'</param>
		public void GetWorkItemsByOwner(int ownerid, int stateid, int statusid, int agentid) {
			ID = ownerid;
			getWorkItems((int) SelectionIdentifier.byOwner, stateid, statusid, agentid);
        }
        ///	<summary>
        ///	Retreives a list of work-items, filtered by the specified process
        /// <param name="procid">The identifier of the 'Process'</param>
        ///	</summary>
        public void GetWorkItemsByProcess(int procid)
        {
            ID = procid;
            getWorkItems((int)SelectionIdentifier.byProcess);
        }
        ///	<summary>
        ///	Retreives a list of work-items, filtered by the specified process
        /// <param name="activateId">The identifier of the activation type (multiple process)</param>
        /// <param name="stateid">The identifier of the state of the tasks</param>
        ///	</summary>
        public void GetWorkItemsByProcess(int activateId, int stateid)
        {
            ID = activateId;
            getWorkItems((int)SelectionIdentifier.byProcessActivation, stateid, 0, 0);
        }
		private void getWorkItems(int idType) {
			_getCommand("xWorkitemsGet", CommandType.StoredProcedure);
			_addDbParameter(ID, "@ID");
			_addDbParameter(idType, "@IDType");
			SqlDataReader rdr = (SqlDataReader) _executeReader(CommandBehavior.Default);
			addWorkItems(rdr);
			rdr.Close();
		}
		private void getWorkItems(int idType, int idState, int idStatus, int idAgent) {
			_getCommand("xWorkitemsSelect", CommandType.StoredProcedure);
			_addDbParameter(ID, "@ID");
			_addDbParameter(idType, "@IDType");
			_addDbParameter(idAgent, "@AgentID");
			_addDbParameter(idState, "@StateID");
			_addDbParameter(idStatus, "@StatusID");
			SqlDataReader rdr = (SqlDataReader) _executeReader(CommandBehavior.Default);
			addWorkItems(rdr);
			rdr.Close();
		}
		private void getWorkItems(int idOwner, int idProcess, int idState, int idStatus, int idAgent) {
			_getCommand("xWorkitemsList", CommandType.StoredProcedure);
			_addDbParameter(idOwner, "@OwnerID");
			_addDbParameter(idProcess, "@ProcessID");
			_addDbParameter(idAgent, "@AgentID");
			_addDbParameter(idState, "@StateID");
			_addDbParameter(idStatus, "@StatusID");
			SqlDataReader rdr = (SqlDataReader) _executeReader(CommandBehavior.Default);
			addWorkItems(rdr);
			rdr.Close();
		}
		private void getWorkItems(int idOwner, int idProcess, int idState, int idStatus, int idAgent, string dateFrom, string dateTo) {
			_getCommand("xWorkitemsListDate", CommandType.StoredProcedure);
			_addDbParameter(idOwner, "@OwnerID");
			_addDbParameter(idProcess, "@ProcessID");
			_addDbParameter(idAgent, "@AgentID");
			_addDbParameter(idState, "@StateID");
			_addDbParameter(idStatus, "@StatusID");
			_addDbParameter(dateFrom, "@DateStart", 20);
			_addDbParameter(dateTo, "@DateEnd", 20);
			SqlDataReader rdr = (SqlDataReader) _executeReader(CommandBehavior.Default);
			addWorkItems(rdr);
			rdr.Close();
        }
        private void getWorkItems(int idOwner, int idProcess, int idProcessType, int idProcessCat, int idState, int idStatus, int idAgent, string dateFrom, string dateTo) {
            _getCommand("xWorkitemsListProcessType", CommandType.StoredProcedure);
            _addDbParameter(idOwner, "@OwnerID");
            _addDbParameter(idProcess, "@ProcessID");
            _addDbParameter(idProcessType, "@ProcessTypeID");
            _addDbParameter(idProcessCat, "@ProcessCatID");
            _addDbParameter(idAgent, "@AgentID");
            _addDbParameter(idState, "@StateID");
            _addDbParameter(idStatus, "@StatusID");
            _addDbParameter(dateFrom, "@DateStart", 20);
            _addDbParameter(dateTo, "@DateEnd", 20);
            SqlDataReader rdr = (SqlDataReader)_executeReader(CommandBehavior.Default);
            addWorkItems(rdr);
            rdr.Close();
        }
		private void addWorkItems(SqlDataReader rdr) {
			x_workflow workflowx = new x_workflow();
			while (rdr.Read()) {
				XmlElement thisitem = workitems.CreateElement("workitem");
				//ProcessID, AgentID, UserID, UserName, UserContact, UserEmail, StartDate, EndDate, StateID, StatusID, ProcessXML, RequestXML
				string agentid = _getString(rdr, "AgentID");
				_addAttribute(workitems, thisitem, "id", _getString(rdr, "ID"));
				_addAttribute(workitems, thisitem, "process", _getString(rdr, "ProcessID"));
				_addElement(workitems, thisitem, "Process", _getString(rdr, "ProcessDescription"), "name", _getString(rdr, "ProcessName"));
				_addAttribute(workitems, thisitem, "agent", agentid);
				_addElement(workitems, thisitem, "Agent", String.Concat(_getString(rdr, "FirstName"), " ", _getString(rdr, "Surname")), "email", _getString(rdr, "EMail"));
				_addAttribute(workitems, thisitem, "state", _getString(rdr, "StateID"));
				_addElement(workitems, thisitem, "State", _getString(rdr, "StateDescription"), "name", _getString(rdr, "StateName"));
				_addAttribute(workitems, thisitem, "status", _getString(rdr, "StatusID"));
				_addElement(workitems, thisitem, "Status", _getString(rdr, "StatusDescription"), "name", _getString(rdr, "StatusName"));
				_addElement(workitems, thisitem, "startdate", _getDate(rdr, "StartDate"));
				_addElement(workitems, thisitem, "enddate", _getDate(rdr, "EndDate"));
				_addElement(workitems, thisitem, "user", "", "ID", _getString(rdr, "UserID"));
				XmlElement userel = (XmlElement) thisitem.SelectSingleNode("user");
				_addElement(workitems, userel, "name", _getString(rdr, "UserName"));
				_addElement(workitems, userel, "contact", _getString(rdr, "UserContact"));
				_addElement(workitems, userel, "email", _getString(rdr, "UserEmail"));
				_addElement(workitems, thisitem, "Request", _getString(rdr, "Request"));
				/*
				_addElement(workitems, thisitem, "Request", "");
				thisitem.SelectSingleNode("request").InnerXml = _getString(rdr, "RequestXML");
				_addElement(workitems, thisitem, "process", "");
				thisitem.SelectSingleNode("process").InnerXml = _getString(rdr, "ProcessXML");
				*/
				
				/* Old logic to get agent details from GK
				// see if this has been added before, if not add it
				XmlElement agent = (XmlElement) WorkItems.SelectSingleNode(String.Concat("workitem[@agent='", agentid, "' and Agent]/Agent"));
				if (agent == null ) {
					try {
						XmlElement gkAgent = workflowx.GetUser(_getString(rdr, "AgentID"));
						_addElement(workitems, thisitem, "Agent", String.Concat(gkAgent.SelectSingleNode("FirstName").InnerText, " ", gkAgent.SelectSingleNode("Surname").InnerText), "email", gkAgent.SelectSingleNode("EMail").InnerText);
					} catch(x_exception) {
						_addElement(workitems, thisitem, "Agent", "[unknown]");
					}
				} else {
					thisitem.AppendChild(agent.CloneNode(true));
				}
				*/
				WorkItems.AppendChild(thisitem);
			}
		}
		
		private void getWorkItems(int id, string contact) {
			_getCommand("xWorkitemsFind", CommandType.StoredProcedure);
			_addDbParameter(id, "@ID");
			_addDbParameter(contact, "@Contact", 30);
			SqlDataReader rdr = (SqlDataReader) _executeReader(CommandBehavior.Default);
			addWorkItems(rdr);
			rdr.Close();
		}
		#endregion
		
		#region Protected methods
		#endregion
				
		#region Private methods
		private void initialise() {
			workitems = new XmlDocument();
			workitems.LoadXml(workitemsxml);
			id = 0;
		}
		#endregion

	}
}
